//=====================================================================
//    COPYRIGHT(C) Innobeam
//    ALL RIGHTS RESERVED
//=====================================================================
//Filename    : router.v rev 1.0
//Created On  : 2018-03-30
//Author      : shilong.zhang
//Description :	route line between CSR PRAM and direct REG
//Include     :
//Modification:
//=====================================================================
module router
(
	iClk			,//clock input
	iRst_n			,//input reset,active low

	//common input sellect signal
	ivAddrSel		,//input 2bit lan9252 working mode sellect signal

	//normal mode input
	iReady_ini		,//input ready signal from lan9252_ini module
	iRdEn_ini		,//input read enable from lan9252_ini module
	ivAddr_ini		,//input address 16bit signal from lan9252_ini module
	ivRData_lan		,//input data 32bit from lan9252_interface module
	idone_lan		,//input done signal from lan9252_interface module
	ivData			,//input data 32bit from lan9252 module extern
	ivAddr			,//input address 16bit from lan9252 module extern
	iWrEn			,//input write enable from lan9252 module extern
	iRdEn			,//input read enable from lan9252 module extern

	//csr mode input
	ivFData_csr		,//input CSR read in data 32bit from lan9252csr_proc module
	iDone_csr		,//input done signal from lan9252csr_proc module
	iLanWr_csr		,//input write enable from lan9252csr_proc module
	iLanRd_csr		,//input read enable from lan9252csr_proc module
	ivLanData_csr	,//input CSR to lan9252_interface data,from lan9252csr_proc module
	ivLanAddr_csr	,//input CSR to lan9252_interface address,from lan9252csr_proc module

	//pram mode input
	iDone_pram		,//input done signal from lan9252pram_proc module
	iLanWr_pram		,//input write enable from lan9252pram_proc module
	iLanRd_pram		,//input read enable from lan9252pram_proc module
	ivLanData_pram	,//input PRAM to lan9252_interface data,from lan9252pram_proc module
	ivLanAddr_pram	,//input PRAM to lan9252_interface address,from lan9252pram_proc module
	iReady_pram		,//input ready signal,from lan9252pram_proc module

	//output to lan_interface
	oWr_lan			,//output write enable to lan9252_interface
	oRd_lan			,//output read enable to lan9252_interface
	ovData_lan		,//output 32bit write data to lan9252_interface
	ovAddr_lan		,//output 16bit address to lan9252_interface
	ovData			,//output 32bit data read from CSR or common reg
	oDone			,//output done signal from CSR PRAM or common reg

	oWr_csr			,//output write enable to lan9252csr_proc
	oRd_csr			,//output read enable to lan9252csr_proc
	ov2Data_csr		,//output 32bit data to be written to lan9252csr_proc
	ovAddr_csr		,//output 16bit address,destination address to lan9252csr_proc

	oWr_pram		,//output write enable to lan9252pram_proc
	oRd_pram		,//output read enable to lan9252pram_proc
	ovAddr_pram		,//output 16bit address,destination address to lan9252pram_proc

	oReady			//output ready signal to lan9252 module extern
);
//========================================================================
//	parameter
//========================================================================
parameter	DATA_W = 16;

//========================================================================
//	port
//========================================================================
input	iClk;
input	iRst_n;//input reset,active low

// common input sellect signal
input	[1:0]	ivAddrSel; // lan9252 working mode sellect signal, 2bit 

// to lan9252 module extern
input	[DATA_W-1:0]	ivAddr;	// 16bit address
input					iWrEn;	// write enable
input	[DATA_W*2-1:0]	ivData;	// 32bit data
input					iRdEn;	// read enable
output					oReady;	// ready signal

// normal mode
input					iReady_ini;		//input ready signal from lan9252_ini module
input					iRdEn_ini;		//input read enable from lan9252_ini module
input	[DATA_W-1:0]	ivAddr_ini;		//input address 16bit signal from lan9252_ini module
input	[DATA_W*2-1:0]	ivRData_lan;	//input data 32bit from lan9252_interface module
input					idone_lan;		//input done signal from lan9252_interface module

output					oWr_lan;	//output write enable to lan9252_interface
output					oRd_lan;	//output read enable to lan9252_interface
output	[DATA_W*2-1:0]	ovData_lan;	//output 32bit write data to lan9252_interface
output	[DATA_W-1:0]	ovAddr_lan;	//output 16bit address to lan9252_interface
output	[DATA_W*2-1:0]	ovData;		//output 32bit data read from CSR or common reg
output					oDone;		//output done signal from CSR PRAM or common reg

//csr mode
input	[DATA_W*2-1:0]	ivFData_csr;	//input CSR read in data 32bit from lan9252csr_proc module
input				  	iDone_csr;		//input done signal from lan9252csr_proc module
input				  	iLanWr_csr;		//input write enable from lan9252csr_proc module
input				  	iLanRd_csr;		//input read enable from lan9252csr_proc module
input	[DATA_W*2-1:0]	ivLanData_csr;	//input CSR to lan9252_interface data,from lan9252csr_proc module
input	[DATA_W-1:0]  	ivLanAddr_csr;	//input CSR to lan9252_interface address,from lan9252csr_proc module

output					oWr_csr;	//output write enable to lan9252csr_proc
output					oRd_csr;	//output read enable to lan9252csr_proc
output	[DATA_W*2-1:0]	ov2Data_csr;	//output 32bit data to be written to lan9252csr_proc
output	[DATA_W-1:0]	ovAddr_csr; //output 16bit address,destination address to lan9252csr_proc

//pram mode
input					iDone_pram      ;//input done signal from lan9252pram_proc module
input					iLanWr_pram     ;//input write enable from lan9252pram_proc module
input					iLanRd_pram     ;//input read enable from lan9252pram_proc module
input	[DATA_W*2-1:0]	ivLanData_pram	;//input PRAM to lan9252_interface data,from lan9252pram_proc module
input	[DATA_W-1:0]	ivLanAddr_pram	;//input PRAM to lan9252_interface address,from lan9252pram_proc module
input					iReady_pram		;//input ready signal,from lan9252pram_proc module

output					oWr_pram		;//output write enable to lan9252pram_proc
output					oRd_pram		;//output read enable to lan9252pram_proc
output	[DATA_W-1:0]	ovAddr_pram		;//output 16bit address,destination address to lan9252pram_proc

//========================================================================
//	localparam
//========================================================================

//========================================================================
//	signal
//========================================================================
reg						oWr_lan;
reg						oRd_lan;
reg		[DATA_W*2-1:0]	ovData_lan;
reg		[DATA_W-1:0]	ovAddr_lan;
reg		[DATA_W*2-1:0]	ovData;
reg						oDone;
reg						oWr_csr;
reg						oRd_csr;
reg		[DATA_W*2-1:0]	ov2Data_csr;
reg		[DATA_W-1:0]	ovAddr_csr;
reg						oWr_pram;
reg						oRd_pram;
reg		[DATA_W-1:0]	ovAddr_pram;

//========================================================================
//	module body
//========================================================================

// Do the corresponding operation according to the ivAddrSel input
// (basic or CSR or PRAM process)
always @ (*) begin
	if(!iRst_n) begin
		oWr_lan 	<= 1'b0;
		oRd_lan 	<= iRdEn_ini;
		ovData_lan 	<= ivData;
		ovAddr_lan 	<= ivAddr_ini;
		ovData 		<= ivRData_lan;
		oDone		<= idone_lan;
		//lan9252csr_proc
		oWr_csr <= 1'b0;
		oRd_csr <= 1'b0;
		ov2Data_csr	<= 	ivData;
		ovAddr_csr	<= 	ivAddr;
		//lan9252pram_proc
		oWr_pram <= 1'b0;
		oRd_pram <= 1'b0;
		ovAddr_pram <= ivAddr;
		end
	else begin
		if(iReady_ini == 1'b0)begin//when in initialization state
			//top interface
			ovData 		<= ivRData_lan;
			oDone		<= idone_lan;

			//lan9252_interface
			oWr_lan 	<= 1'b0;
			oRd_lan 	<= iRdEn_ini;
			ovData_lan 	<= ivData;
			ovAddr_lan 	<= ivAddr_ini;

			//lan9252csr_proc
			oWr_csr <= 1'b0;
			oRd_csr <= 1'b0;
			ov2Data_csr	<= 	ivData;
			ovAddr_csr	<= 	ivAddr;

			//lan9252pram_proc
			oWr_pram <= 1'b0;
			oRd_pram <= 1'b0;
			ovAddr_pram <= ivAddr;
			end
		else begin //normal working state
			case(ivAddrSel)
				2'b00: begin
					//top interface
					ovData 		<= ivRData_lan;
					oDone		<= idone_lan;

					//lan9252_interface
					oWr_lan 	<= iWrEn;
					oRd_lan 	<= iRdEn;
					ovData_lan 	<= ivData;
					ovAddr_lan 	<= ivAddr;

					//lan9252csr_proc
					oWr_csr <= 1'b0;
					oRd_csr <= 1'b0;
					ov2Data_csr	<= 	ivData;
					ovAddr_csr	<= 	ivAddr;

					//lan9252pram_proc
					oWr_pram <= 1'b0;
					oRd_pram <= 1'b0;
					ovAddr_pram <= ivAddr;
					end
				2'b01: begin
					//top interface
					ovData 		<= 	ivFData_csr;
					oDone		<= 	iDone_csr;

					//lan9252_interface
					oWr_lan 	<= 	iLanWr_csr;
					oRd_lan 	<= 	iLanRd_csr;
					ovData_lan 	<= 	ivLanData_csr;
					ovAddr_lan 	<= 	ivLanAddr_csr;

					//lan9252csr_proc
					oWr_csr 	<= 	iWrEn;
					oRd_csr 	<= 	iRdEn;
					ov2Data_csr	<= 	ivData;
					ovAddr_csr	<= 	ivAddr;

					//lan9252pram_proc
					oWr_pram <= 1'b0;
					oRd_pram <= 1'b0;
					ovAddr_pram <= ivAddr;
					end
				2'b10: begin
					//top interface
					oDone		<= iDone_pram;
					ovData 		<= ivRData_lan;

					//lan9252_interface
					oWr_lan 	<= iLanWr_pram;
					oRd_lan 	<= iLanRd_pram;
					ovData_lan 	<= ivLanData_pram;
					ovAddr_lan 	<= ivLanAddr_pram;

					//lan9252csr_proc
					oWr_csr 	<= 	1'b0;
					oRd_csr 	<= 	1'b0;
					ov2Data_csr	<= 	ivData;
					ovAddr_csr	<= 	ivAddr;

					//lan9252pram_proc
					oWr_pram <= iWrEn;
					oRd_pram <= iRdEn;
					ovAddr_pram <= ivAddr;
					end
				default: begin
					//top interface
					ovData 		<= ivRData_lan;
					oDone		<= idone_lan;

					//lan9252_interface
					oWr_lan 	<= iWrEn;
					oRd_lan 	<= iRdEn;
					ovData_lan 	<= ivData;
					ovAddr_lan 	<= ivAddr_ini;

					//lan9252csr_proc
					oWr_csr <= 1'b0;
					oRd_csr <= 1'b0;
					ov2Data_csr	<= 	ivData;
					ovAddr_csr	<= 	ivAddr;

					//lan9252pram_proc
					oWr_pram <= 1'b0;
					oRd_pram <= 1'b0;
					ovAddr_pram <= ivAddr;
					end
			endcase
			end//else
		end//else
	end//always

assign oReady = iReady_ini & iReady_pram;

endmodule
